#ifndef HLS_PROTOCOL_CLIENT_H_
#define HLS_PROTOCOL_CLIENT_H_

#include "public_module/protocol_connection/http_protocol_operation.h"

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

class ProtocolConnection;
class HlsProtocolOperation;
class Loop;
class HlsM3U8Message;
class HlsProtocolClient
{
public:
    explicit HlsProtocolClient(Loop * loop);
    void Path(const std::string & hls_file_path, const std::string & media_file_path);
    int  InitM3U8Url(const std::string & url);

private:
    void OnConnection(ProtocolConnection * connection, int result) const;
    void OnMessage(ProtocolConnection * connection, HlsProtocolOperation * operate);
    void OnConnError(ProtocolConnection * connection, int);
    void SendRequest(ProtocolConnection * connection, HttpRequest & request) const;
    void SendHeadRequest(ProtocolConnection * connection) const;
    void ComposeMediaUrl(HlsM3U8Message * message);
    int  WriteM3U8File(const std::string & filename, const std::string & content) const;
    void WriteToFile(const std::string & filename, std::vector<uint8_t> & data) const;
    void WriteToFileAppend(const std::string & filename, std::vector<uint8_t> & data) const;

    class RequestMediaData;
    void ResourceOnConnect(ProtocolConnection * connection, int result, std::shared_ptr<RequestMediaData> request_media_data);
    void ResourceOnMessage(ProtocolConnection * connection, HlsProtocolOperation * operate, std::shared_ptr<RequestMediaData> request_media_data);
    void ResourceOnConnError(ProtocolConnection * connection, int, std::shared_ptr<RequestMediaData> request_media_data);
private:
    Loop *                 m_loop;
    ProtocolConnection *   m_hls_connection{};
    HlsProtocolOperation * m_hls_operate{};
    struct ResourceUri
    {
        std::string m_file_md5;
        std::string m_url;
    };
    struct RequestMediaData
    {
        ProtocolConnection    * m_http_connection{};
        HttpProtocolOperation * m_http_operate{};
        ResourceUri             m_uri;
    };
    std::vector<std::shared_ptr<RequestMediaData>> m_request_media_vec;
    std::vector<ResourceUri>                       m_media_url_vec;
    std::string                                    m_m3u8_url;

private:
    std::string m_domain;
    std::string m_hls_file_path;
    std::string m_media_file_path;
};

#endif
